home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 127_01.zip / RAP4.C < prev    next >
Text File  |  1993-06-17  |  19KB  |  694 lines

  1. /*********************************************************************\
  2. ** .---------------------------------------------------------------. **
  3. ** |                                                               | **
  4. ** |                                                               | **
  5. ** |         Copyright (c) 1981, 1982, 1983 by Eric Martz.         | **
  6. ** |                                                               | **
  7. ** |                                                               | **
  8. ** |       Permission is hereby granted to use this source         | **
  9. ** |       code only for non-profit purposes. Publication of       | **
  10. ** |       all or any part of this source code, as well as         | **
  11. ** |       use for business purposes is forbidden without          | **
  12. ** |       written permission of the author and copyright          | **
  13. ** |       holder:                                                 | **
  14. ** |                                                               | **
  15. ** |                          Eric Martz                           | **
  16. ** |                         POWER  TOOLS                          | **
  17. ** |                    48 Hunter's Hill Circle                    | **
  18. ** |                      Amherst MA 01002 USA                     | **
  19. ** |                                                               | **
  20. ** |                                                               | **
  21. ** `---------------------------------------------------------------' **
  22. \*********************************************************************/
  23.  
  24. #include "rap.h"
  25.  
  26. /*------------------------------------------------------------------------*/
  27. init_ss() {
  28.     FILE *fpss;
  29.     int c, junk;
  30.  
  31.     Ss_pair_cnt = 0;
  32.     Oldnewtot = 0;
  33.  
  34.     /* GET STRINGS FROM SSn */
  35.     fpss = fopen(Ss_name,"r-");
  36.     if (!fpss) {
  37.         fprintf(STDERR,"Warning: file \"%s\" does not exist.\n",Ss_name);
  38.         return(0);
  39.     }
  40.     fprintf(STDERR,"Reading file \"%s\":\n",Ss_name);
  41.  
  42.     /* PROCESS CONTENTS OF *.SS FILE */
  43.     /* ONLY BLANK LINES, COMMENTS ALLOWED BEFORE COMMANDS */
  44.  
  45.     FOREVER {
  46.         c = getc(fpss);
  47.         switch (c) {
  48.             case '\n':
  49.             case '\r':
  50.                 /* INGNORE BLANK LINES */
  51.                 break;
  52.             case '!':
  53.                 /* READ AND IGNORE REMAINDER OF LINE */
  54.                 rapgets(Inbuf,fpss);
  55.                 break;
  56.             case COMMAND:
  57.                 ungetc(c,fpss);
  58.                 rapgets(Inbuf,fpss);
  59.                 de_comment(Inbuf);
  60.                 command(Inbuf, Nxname, &junk);
  61.                 break;
  62.             default:
  63.                 goto pastcomms;
  64.         }
  65.     }
  66. pastcomms:
  67.     if (c EQ EOF) c = CPMEOF;
  68.     ungetc(c,fpss);
  69.  
  70.     /* GET SUBSTITUTION PAIRS AND HARDWARE INFO */
  71.     if (!getpairs(fpss, Ss_name)) {
  72.         fprintf(STDERR, "ERROR in SS file:\n");
  73.         fprintf(STDERR, "  }u+}, }u-}, }b+}, or }b-} is missing.\n");
  74.     }
  75.  
  76.     fpfree(fpss);
  77.  
  78.     /* put "}RF}" in Oldstring[0] for use in ss() */
  79.     Inbuf[0] = Post_ss_delim;
  80.     Inbuf[1] = NULL;
  81.     strcat(Inbuf,"RF");
  82.     Inbuf[3] = Post_ss_delim;
  83.     Inbuf[4] = NULL;
  84.     Oldstring[0] = pack(Oldnewbuf,&Oldnewtot,MAXPACK,Inbuf);
  85. }
  86. /*------------------------------------------------------------------------*/
  87. ss(bf,mark)
  88.     char *bf, *mark;
  89.     {
  90.     char double_delim[3], newrf[5], prompt[3], delim_str[2], wait[7];
  91.     char up[3], down[3], under[3], bold[3], arab[8];
  92.     int start, stop, i, pr;
  93.  
  94.     delim_str[0] = *mark;
  95.     delim_str[1] = NULL;
  96.     wait[0] = Post_ss_delim;
  97.     wait[1] = NULL;
  98.     strcpy(wait, "wait");
  99.     wait[5] = Post_ss_delim;
  100.     wait[6] = NULL;
  101.     up[0] = down[0] = under[0] = bold[0] = Pre_ss_delim;
  102.     up[1] = 'u';
  103.     down[1] = 'd';
  104.     under[1] = '_';
  105.     bold[1] = '!';
  106.     up[2] = down[2] = under[2] = bold[2] = NULL;
  107.  
  108.  
  109. #ifdef DEBUG
  110.     if (Debug) {
  111.         fprintf(STDERR,"Entering ss%s:",mark);
  112.         checkbig("",bf);
  113.     }
  114. #endif
  115.     stop = 0;
  116.  
  117.     /* CONVERT CONSOLE PROMPT DELIMITERS */
  118.     prompt[0] = Post_ss_delim;
  119.     prompt[1] = '"';
  120.     prompt[2] = NULL;
  121.     while (mark[0] EQ Post_ss_delim
  122.         AND (i = instr(0, bf, prompt)) NE ERROR) {
  123.  
  124.         bf[i] = c1(PROMPT);
  125.         pr = i;
  126.         do {    /* SHIFT DOWN TO DELETE " */
  127.             i++;
  128.             bf[i] = bf[i+1];
  129.         } while (bf[i]);
  130.  
  131.         i = instr(pr, bf, delim_str);
  132.         if (i EQ ERROR) {
  133.             i = strlen(bf);
  134.             bf[i+1] = NULL;
  135.         }
  136.         bf[i] = c1(PROMPT);
  137.     }
  138.  
  139.     /* SQUEEZE BLANKS OUT OF ORIGINAL STRINGS FOR SUBSTITUTION */
  140.     while ((start = instr(stop, bf, mark)) NE -1) {
  141.  
  142.         stop = instr(start+1, bf, mark);
  143.         if (stop EQ -1) {
  144.             fprintf(STDERR,
  145. "Incomplete \"%s\"-delimited substitution string at line %d:\n",
  146.                 mark,In_linecnt);
  147.             checkbig("",bf);
  148.             exit(0);
  149.         }
  150.         stop = stop +1;
  151.             /* -(delchars(bf+start, bf+stop, " ")); defeated 2.21 */
  152.     }
  153. #ifdef DEBUG
  154.     if (Debug AND stop NE 0) checkbig("",bf);
  155. #endif
  156.     /* NO SUBSTITUTIONS NECESSARY */
  157.     /* IF \\ THEN SS IS NOT CALLED UNLESS \\ OR Press_all */
  158.     if (stop EQ 0 AND mark[0] EQ Post_ss_delim) return(0);
  159.  
  160.     /* INSTALL AUTO-INCREMENTING ARABIC NUMBER IF NEEDED */
  161.     if (mark[0] EQ Pre_ss_delim) {
  162.         arab[0] = Pre_ss_delim;
  163.         arab[1] = '#';
  164.         arab[2] = NULL;
  165.         if ((i=instr(0, bf, arab)) NE ERROR) {
  166.             if (bf[i+2] EQ '+') Arabic++;
  167.             sprintf(newrf, "%d", Arabic);
  168.             arab[2] = '+';
  169.             arab[3] = Pre_ss_delim;
  170.             arab[4] = NULL;
  171.             if (bf[i+2] EQ '+') substitute(bf, arab, newrf);
  172.             else {
  173.                 arab[2] = Pre_ss_delim;
  174.                 arab[3] = NULL;
  175.                 substitute(bf, arab, newrf);
  176.             }
  177.         }
  178.     }
  179.     
  180.     /* EXPAND SUPERSCRIPT/SUBSCRIPT MACRO */
  181.     if (mark[0] EQ Pre_ss_delim) {
  182.         start = 0;
  183.         while ((start=instr(start,bf, up)) NE ERROR)
  184.             updown(bf,start,'u');
  185.         start = 0;
  186.         while ((start=instr(start,bf, down)) NE ERROR)
  187.             updown(bf,start,'d');
  188.         start = 0;
  189.         while ((start=instr(start,bf, under)) NE ERROR)
  190.             updown(bf,start,'_');
  191.         start = 0;
  192.         while ((start=instr(start,bf, bold)) NE ERROR)
  193.             updown(bf,start,'!');
  194.     }
  195.     
  196.     /* WAIT */
  197.     if (mark[0] EQ Post_ss_delim) substitute(bf, wait, WAIT);
  198.     
  199.     /* MAIN SUBSTITUTION LOOP */
  200.     for (i = 1; i <= Ss_pair_cnt; i++) {
  201.         if (*Oldstring[i] EQ mark[0]
  202.             OR
  203.  
  204.             /* FOR NON-DELIMITED ORIGINAL STRINGS (WHICH MUST HAVE BEEN
  205.                 SUFFIXED WITH '@' IN THE SSn FILE) */
  206.  
  207.             (mark[0] EQ Pre_ss_delim
  208.             AND
  209.             *Oldstring[i] NE Post_ss_delim))
  210.  
  211.             substitute (bf, Oldstring[i], Newstring[i]);
  212.     }
  213.  
  214.     /* RESTORE FONT IF REQUESTED */
  215.     if (mark[0] EQ Post_ss_delim AND Font_o) {
  216.         sprintf(newrf, "%s%d%s", Font_o, Font, Font_c);
  217.         substitute(bf, Oldstring[0], newrf);
  218.             /* Oldstring[0] was initialized to "}RF}" in init_ss */
  219.     }
  220.     
  221.     /* CONVERT }} TO } AND {{ TO { */
  222.     if (bf[0] NE COMMAND) {
  223.         double_delim[0] = double_delim[1] = mark[0];
  224.         double_delim[2] = NULL;
  225.         substitute (bf, double_delim, mark);
  226.     }
  227.  
  228. #ifdef DEBUG
  229.     if (Debug) checkbig("ss done:",bf);
  230. #endif
  231. }
  232.  
  233. /*------------------------------------------------------------------------*/
  234. expantab(bf)
  235.     char *bf;
  236.     {
  237.     int b, t, inss, pos;
  238.     char tmp[BIGBUF];
  239.     
  240.     /* IF THERE'S NO TAB, RETURN */
  241.     if ((b=instr(0,bf,"\t")) EQ -1) return(0);
  242.     
  243.     /* IF THERE'S A TAB, TRANSFER PRE-TAB STRING TO TMP */
  244.     for (t=0, pos=0; t<b; t++, pos++) tmp[t] = bf[t];
  245.     t = b;
  246.     
  247.     /* EXPAND TABS, TAKING POST-SUBSTITUTIONS INTO ACCOUNT */
  248.     inss = 0;
  249.     while (bf[b]) {
  250.         if (bf[b] NE TAB) {
  251.             if (bf[b] EQ Post_ss_delim) {
  252.                 if (!inss) inss = YES; /* OPENING DELIM */
  253.                 if (!inss) pos++;
  254.                 if (inss) inss = NO; /* CLOSING DELIM */
  255.             }
  256.             else if (!inss) pos++;
  257.             tmp[t++] = bf[b++];
  258.         }
  259.         else {
  260.             do {
  261.                 tmp[t++] = SPACE;
  262.                 pos++;
  263.             } while (pos%Tabval);
  264.             b++;
  265.         }
  266.     }
  267.     tmp[t] = NULL;
  268.     strcpy(bf, tmp);
  269. }
  270. /*------------------------------------------------------------------------*/
  271. /* FNNLGETS = File-No-NewLine-GET-String
  272. SAME AS FGETS BUT STRING LEFT IN S IS STRIPPED OF THE TERMINAL NEWLINE.
  273. RAPGETS: SETS Press_flg +  FOR EVEN NUMBER OF Pre_ss_delim, - FOR ODD,
  274. 0 FOR NONE. */
  275.  
  276. rapgets(s,fp)
  277.     char *s;
  278.     FILE *fp;
  279.     {
  280.     char *p;
  281.     int length;
  282.     Press_flg = 0;
  283.     if ((length = biggets(s,fp)) EQ 0) return(0);
  284.     In_linecnt++;
  285.     if (Pre_ss) for(p = s; *p; p++) {
  286.         if (*p EQ Pre_ss_delim) {
  287.             if (Press_flg >= 0) Press_flg = -1;
  288.             else Press_flg = 1;
  289.         }
  290.     }
  291.     /* TRIMS OFF TERMINAL NEWLINE */
  292.     if (s[length-1] EQ '\n') s[length-1] = NULL;
  293.     return(1);
  294. }
  295. /*------------------------------------------------------------------------*/
  296. checkbig(m,s)
  297. /* ROUTINE TO WRITE STRINGS TOO BIG FOR FPRINTF TO STDERR */
  298.     char *m, *s;
  299.     {
  300.     while (*m) putc(*m++,STDERR);
  301.     if (*s) {
  302.         putc('<',STDERR);
  303.         while (*s) putc(*s++,STDERR);
  304.         if (*(s-1) NE NEWLINE)
  305.             fputs(">\n",STDERR);
  306.     }
  307. }
  308. /*------------------------------------------------------------------------*/
  309. /*
  310.     fgets:
  311.     This next function is like "gets", except that
  312.     a) the line is taken from a buffered input file instead
  313.     of from the console, and b) the newline is INCLUDED in
  314.     the string and followed by a null byte. 
  315.     
  316.     This one is a little tricky due to the CP/M convention
  317.     of having a carriage-return AND a linefeed character
  318.     at the end of every text line. In order to make text
  319.     easier to deal with from C programs, this function (fgets)
  320.     automatically strips off the CR from any CR-LF combinations
  321.     that come in from the file. Any CR characters not im-
  322.     mediately followed by LF are left intact. The LF
  323.     is included as part of the string, and is followed
  324.     by a null byte. (Note that LF equals "newline".)
  325.     There is no limit to how long a line
  326.     can be here; care should be taken to make sure the
  327.     string pointer passed to fgets points to an area
  328.     large enough to accept any possible line length
  329.     (a line must be terminated by a newline (LF, or '\n')
  330.     character before it is considered complete.)
  331.  
  332.     The value NULL (defined to be 0 here) is returned
  333.     on EOF, whether it be a physical EOF (attempting to
  334.     read past last sector of the file) OR a logical EOF
  335.     (encountered a control-Z.) The 1.3 version didn't
  336.     recognize logical EOFs, because I did't realize how
  337.     SIMPLE it was to implement a buffered I/O "ungetc"
  338.     function.
  339. */
  340.  
  341. int biggets(s,iobuf)
  342.     char *s;
  343.     FILE *iobuf;
  344.     {
  345.     int count, c;
  346.     char *cptr;
  347.     count = BIGBUF-1;
  348.     cptr = s;
  349.     if ( (c = getc(iobuf)) == EOF) return NULL;
  350.  
  351.     do {
  352.         if ((*cptr++ = c) == '\n') {
  353.             if (cptr>s+1 && *(cptr-2) == '\r')
  354.                 *(--cptr - 1) = '\n';
  355.             break;
  356.         }
  357.     } while (count-- && (c=getc(iobuf)) != EOF);
  358.     if (count <= 0) fprintf(STDERR,
  359. "Line %d is too long [biggets()]; input lines must be <%d characters.\n",
  360.         In_linecnt,BIGBUF);
  361.     if (c == EOF) ungetc(CPMEOF, iobuf);    /* push back control-Z */
  362.     *cptr = NULL;
  363. #ifdef DEBUG
  364.     if(Debug) checkbig("BIGGETS:", s);
  365. #endif
  366.     return (BIGBUF-1 - count);
  367. }
  368.  
  369. /*------------------------------------------------------------------------*/
  370. /* DELETE TERMINAL COMMENTS PRECEDED WITH "!"; "!!" = "!" */
  371.  
  372. de_comment(buf)
  373.     char *buf;
  374.     {
  375.     int i;
  376.     i = 0;
  377.     while ((i = instr(i,buf,"!")) != -1) {
  378.         if (buf[i+1] == '!') {
  379.             strcpy(buf+i,buf+i+1); /* "!!" = "!" */
  380.             i++;
  381.         }
  382.         else buf[i] = NULL; /* CHOP OFF COMMENTS */
  383.     }
  384. }
  385. /*------------------------------------------------------------------------*/
  386. updown(buf,start,direction)
  387.  
  388. /* CALLED WHEN
  389.     buf CONTAINS A STRING INCLUDING "{{u" OR "{d" AT buf[start]
  390.     direction IS 'u' OR 'd'
  391.  
  392.     THIS FUNCTION REPLACES, FOR EXAMPLE
  393.     
  394.         ...{u51{Cr release...
  395.         
  396.     WITH
  397.     
  398.         ...}u1}51}d2}Cr release...
  399.  
  400.     THUS THE FOLLOWING MUST BE DEFINED:
  401.     
  402.         }u1}, }d2} and }d1}, }u2}
  403.  
  404.     FOR EXAMPLE:
  405.     
  406.         }u1}
  407.         }u}}font2} !NOTE NO SPACES ALLOWED SINCE COMPRESSION PRECEDES
  408.         
  409.         }d2}
  410.         }d}}RF}
  411.     */
  412.  
  413.     char *buf;
  414.     int start, direction;
  415.     {
  416.     int stop;
  417.     char *after, left[MAXLINE], delim_str[2];
  418.     char b1[5], b2[5], u1[5], u2[5];
  419.     char post[5];
  420.  
  421.     delim_str[0] = Pre_ss_delim;
  422.     delim_str[1] = NULL;
  423.     makebu(b1, b2, u1, u2);
  424.  
  425.     after = Ulbuf;
  426.     buf[start] = NULL;
  427.     strcpy(after, buf);
  428.     switch (direction) {
  429.         case 'u':
  430.             strcat(after, posttwo(post, 'u', '1'));
  431.             break;
  432.         case 'd':
  433.             strcat(after, posttwo(post, 'd', '1'));
  434.             break;
  435.         case '_':
  436.             strcat(after, u1);
  437.             break;
  438.         case '!':
  439.             strcat(after, b1);
  440.             break;
  441.     }
  442.     stop = instr(start+2,buf, delim_str);
  443.     if (stop NE ERROR) buf[stop] = NULL;
  444.     strcat(after, buf+start+2);
  445.     switch (direction) {
  446.         case 'u':
  447.             strcat(after, posttwo(post, 'd', '2'));
  448.             break;
  449.         case 'd':
  450.             strcat(after, posttwo(post, 'u', '2'));
  451.             break;
  452.         case '_':
  453.             strcat(after, u2);
  454.             break;
  455.         case '!':
  456.             strcat(after, b2);
  457.             break;
  458.     }
  459.     if (stop NE ERROR) strcat(after,buf+stop+1);
  460.     strcpy(buf,after);
  461. }
  462. /*------------------------------------------------------------------------*/
  463. char *posttwo(bf, one, two)
  464.     char *bf, one, two;
  465.     {
  466.     bf[0] = Post_ss_delim;
  467.     bf[1] = one;
  468.     bf[2] = two;
  469.     bf[3] = Post_ss_delim;
  470.     bf[4] = NULL;
  471.     return(bf);
  472. }
  473. /*------------------------------------------------------------------------*/
  474. getpairs(fpss, sslist)
  475.     FILE *fpss;
  476.     char *sslist;
  477.     {
  478.     char bf2[MAXLINE], pssd, *o, *n, built_in;
  479.     int i, old, oldold, eof_flag, summary, lastchar, u1, u2, b1, b2;
  480.  
  481.     u1 = u2 = b1 = b2 = NO;
  482. /*    summary = !Ss_pair_cnt;*/
  483.     summary = YES;
  484.     if (Ss_pair_count) summary = NO;
  485.     if (Ss_pair_cnt EQ -1) Ss_pair_cnt = 0;
  486.     old = YES;
  487.     eof_flag = NO;
  488.  
  489.     while(ssgets(Inbuf,fpss)) { /* OR FNNGETS */
  490.  
  491. #ifdef DEBUG
  492.         if (Debug) checkbig("getpairs",Inbuf);
  493. #endif
  494.         de_comment(Inbuf);
  495.  
  496.         /* SKIP BLANK LINES WHILE LOOKING FOR OLD STRING */
  497.         if (old && !strlen(Inbuf)) continue;
  498.  
  499.         /* CONCATENATE NEW STRINGS UNTIL BLANK LINE */
  500.         if (!old) {
  501.             if ((ssgets(bf2,fpss)) EQ 0) {
  502.                 eof_flag = YES;
  503.                 goto eof;
  504.             }
  505.             de_comment(bf2);
  506.             while (strlen(bf2)) {
  507.                 if (Inbuf[strlen(Inbuf)-1] EQ '_')
  508.                     Inbuf[strlen(Inbuf)-1] = NULL;
  509.                 else strcat(Inbuf,"\r\n");
  510.                 strcat(Inbuf, bf2);
  511.                 if ((ssgets(bf2,fpss)) EQ 0) {
  512.                     eof_flag = YES;
  513.                     break;
  514.                 }
  515.                 de_comment(bf2);
  516.             }
  517.         }
  518. eof:
  519. #ifdef DEBUG
  520.         if (Debug) {
  521.             fprintf(STDERR,"GOT(%d)",strlen(Inbuf));
  522.             checkbig("",Inbuf);
  523.         }
  524. #endif
  525.         if(Ss_pair_cnt+1 > MAXPAIRS-1) {
  526.             printf("Too many pairs in SS file (Max = %d).\n",
  527.                 MAXPAIRS-1);
  528.             exit(0);
  529.         }
  530.  
  531.         substitute(Inbuf,"|N","\n");
  532.         substitute(Inbuf,"|R","\r");
  533.         lastchar = strlen(Inbuf)-1;
  534.         if (old) {
  535.             if (equal(Inbuf,"i/o port")) {
  536.                 io_port(fpss);
  537.                 continue;
  538.             }
  539.             if (equal(Inbuf,"baud")) {
  540.                 baud(fpss);
  541.                 continue;
  542.             }
  543.             if (Inbuf[lastchar] EQ '@') {
  544.                 Inbuf[lastchar] = NULL;
  545.                 Press_all = YES;
  546.                 lastchar--;
  547.             }
  548.             else {
  549.                 /* LEADING SPACE IN }...} MEANS NOT BUILT IN */
  550. /*                built_in = !(Inbuf[1] EQ ' ');*/
  551.                 built_in = YES;
  552. /*                if (Inbuf[1] EQ ' ') built_in = NO; defeated 2.21 */
  553. /*                delchars(Inbuf,0," "); defeated 2.21 */
  554.                 lastchar = strlen(Inbuf)-1;
  555.  
  556.                 if ((Inbuf[0] NE Pre_ss_delim
  557.                 AND Inbuf[0] NE Post_ss_delim)
  558.                 OR
  559.                 (Inbuf[lastchar] NE Pre_ss_delim
  560.                 AND Inbuf[lastchar] NE Post_ss_delim)
  561.                 OR
  562.                 (Inbuf[0] EQ Pre_ss_delim
  563.                 AND Inbuf[lastchar] EQ Post_ss_delim)
  564.                 OR
  565.                 (Inbuf[lastchar] EQ Pre_ss_delim
  566.                 AND Inbuf[0] EQ Post_ss_delim)){
  567.  
  568.                     fprintf(STDERR,
  569. "\nInvalid delimiters (%c,%c) around original string in %s:\n\"%s\"\n",
  570.                         Pre_ss_delim, Post_ss_delim,sslist,Inbuf);
  571.                     exit(0);
  572.                 }
  573.             }
  574.             oldold = 0;
  575.             for (i=1; i<=Ss_pair_cnt; i++) {
  576.                 if (equal(Inbuf, Oldstring[i])) {
  577.                     oldold = i;
  578.                     break;
  579.                 }
  580.             }
  581.             if (!oldold) Oldstring [Ss_pair_cnt + 1] =
  582.                 pack(Oldnewbuf,&Oldnewtot,MAXPACK,Inbuf);
  583.             old = NO;
  584. #ifdef DEBUG
  585.             if (Debug) fprintf(STDERR,
  586.                 "Old:<%s>[Oldnewtot=%d]\n",Inbuf,Oldnewtot);
  587. #endif
  588.             if (Oldnewtot >= MAXPACK) {
  589.                 fprintf(STDERR,
  590. "Out of storage space for string substitution pairs during reading of %s.\n",
  591.                     sslist);
  592.                 exit(0);
  593.             }
  594.         }
  595.         else {
  596.             if (oldold) i = oldold;
  597.             else i = Ss_pair_cnt + 1;
  598.             Newstring [i] =
  599.                 pack(Oldnewbuf,&Oldnewtot,MAXPACK,Inbuf);
  600.  
  601.             if (built_in) {
  602.                 o = 1 + Oldstring[Ss_pair_cnt+1];
  603.                 n = Newstring[Ss_pair_cnt+1];
  604.                 pssd = Post_ss_delim;
  605.                 if (lefteq(o,"init") EQ 4 AND o[4] EQ pssd) Init = n;
  606.                 if (lefteq(o,"deinit") EQ 6 AND o[6] EQ pssd) Deinit = n;
  607.                 if (lefteq(o,"left") EQ 4 AND o[4] EQ pssd)
  608.                     Flush_left = n;
  609.                 if (lefteq(o,"right") EQ 5 AND o[5] EQ pssd)
  610.                     Flush_right = n;
  611.                 if (lefteq(o,"center") EQ 6 AND o[6] EQ pssd)
  612.                     Center_mode = n;
  613.                 if (lefteq(o,"just1") EQ 5 AND o[5] EQ pssd) Just_one = n;
  614.                 if (lefteq(o,"just2") EQ 5 AND o[5] EQ pssd) Just_two = n;
  615.                 if (lefteq(o,"fn-open") EQ 7 AND o[7] EQ pssd) Font_o = n;
  616.                 if (lefteq(o,"fn-close") EQ 8 AND o[8] EQ pssd)
  617.                     Font_c = n;
  618.                 if (lefteq(o,"forceprint") EQ 10 AND o[10] EQ pssd)
  619.                     Forceprint = n;
  620.                 if (lefteq(o,"u+") EQ 2 AND o[2] EQ pssd) {
  621.                     Ul_on = n;
  622.                     u1 = YES;
  623.                 }
  624.                 if (lefteq(o,"u-") EQ 2 AND o[2] EQ pssd) {
  625.                     Ul_off = n;
  626.                     u2 = YES;
  627.                 }
  628.                 if (lefteq(o,"b+") EQ 2 AND o[2] EQ pssd) {
  629.                     Bo_on = n;
  630.                     b1 = YES;
  631.                 }
  632.                 if (lefteq(o,"b-") EQ 2 AND o[2] EQ pssd) {
  633.                     Bo_off = n;
  634.                     b2 = YES;
  635.                 }
  636.                 if (lefteq(o,"bo-shift") EQ 8 AND o[8] EQ pssd)
  637.                     Bo_shift = n;
  638.                 if (lefteq(o,"bo-restore") EQ 10 AND o[10] EQ pssd)
  639.                     Bo_restore = n;
  640.                 if (lefteq(o,"ul-shift") EQ 8 AND o[8] EQ pssd)
  641.                     Ul_shift = n;
  642.                 if (lefteq(o,"ul-restore") EQ 10 AND o[10] EQ pssd)
  643.                     Ul_restore = n;
  644.                 if (lefteq(o,"rlf") EQ 3 AND o[3] EQ pssd) Rev_lf = n;
  645.             }
  646.             old = YES;
  647. #ifdef DEBUG
  648.             if (Debug) {
  649.                 fprintf(STDERR,"New[Oldnewtot=%d]:",Oldnewtot);
  650.                 checkbig("",Inbuf);
  651.             }
  652. #endif
  653.             if (Oldnewtot >= MAXPACK) {
  654.                 fprintf(STDERR,
  655. "Out of storage space for string substitution pairs during reading of %s.\n",
  656.                     sslist);
  657.                 exit(0);
  658.             }
  659.         }
  660.         if (old AND !oldold) Ss_pair_cnt++;
  661.         if (eof_flag) break;
  662.     }
  663.     if (!Screen_size OR summary) {
  664.         fprintf(STDERR,"\tSS Pair count = %d\n",Ss_pair_cnt);
  665.         old = ((MAXPACK + 50)/100);
  666.         fprintf(STDERR,"\tSS Pair Buffer %d%% Full.\n",
  667.             ((((10 * Oldnewtot)/old) +5)/10));
  668.     }
  669.     if (!Ss_pair_cnt) Ss_pair_cnt = -1;
  670.     if (u1 AND u2 AND b1 AND b2) return(YES);
  671.     else return(NO);
  672. }
  673. /*------------------------------------------------------------------------*/
  674. ssgets(buf, fp)
  675.     char *buf;
  676.     FILE *fp;
  677.     {
  678.     if (!rapgets(buf, fp)) return(NO);
  679.     if ((lefteq(buf,".ss 0")) EQ 5) return(NO);
  680.     if ((lefteq(buf,".ss 1")) EQ 5) {
  681.         fprintf(STDERR,
  682. "Error: Second consecutive '.ss 1' command at line %d\n", In_linecnt);
  683.         exit(0);
  684.     }
  685.     if ((lefteq(buf,".ss")) EQ 3)
  686.         fprintf(STDERR,
  687. "Warning: possible invalid '.ss' command at line %d\n", In_linecnt);
  688.     return(YES);
  689. }
  690. /*------------------------------------------------------------------------*/
  691. /*    END of RAP4.C    */
  692. /*------------------------------------------------------------------------*/
  693. r_cnt++;
  694.